package teehee.DB;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Scanner;

import teehee.homepage.R;

import android.content.Context;
import android.content.res.Resources;

/**
 * @author Shubham
 *
 */
public class DBHistory {
	
	private String date;
	private String name;
	private String reps;
	private String time;
	private String weight;
	private String comment;
	private ArrayList<String> exList;
	private static ArrayList<DBHistory> db_wodHistory = new ArrayList<DBHistory>();
	
	/**
	 * Private c'tor to instantiate the object
	 * @param date
	 * @param name
	 * @param reps
	 * @param time
	 * @param weight
	 * @param comment
	 * @param exList
	 */
	
	private DBHistory(String date, String name, String reps, String time, String weight, String comment, ArrayList<String> exList)
	{
		this.date = date;
		this.name = name;
		this.reps = reps;
		this.time = time;
		this.weight = weight;
		this.comment = comment;
		this.exList = exList;
	}
		
	/**
	 * Method to return the date.
	 * @param  none
	 * @return String
	 * @see
	*/
	public String getDate()
	{
		return this.date;
	}
		
	/**
	 * Method to return the name.
	 * @param  none
	 * @return String
	 * @see
	*/
	public String getName()
	{
		return this.name;
	}


	/**
	 * Method to return the reps.
	 * @param  none
	 * @return String
	 * @see
	*/
	public String getReps()
	{
		return this.reps;
	}

	/**
	 * Method to return the time.
	 * @param  none
	 * @return String
	 * @see
	*/
	public String getTime()
	{
		return this.time;
	}

	/**
	 * Method to return the weights.
	 * @param  none
	 * @return String
	 * @see
	*/
	public String getWeights()
	{
		return this.weight;
	}

	/**
	 * Method to return the comments.
	 * @param  none
	 * @return String
	 * @see
	*/
	public String getComments()
	{
		return this.comment;
	}

	/**
	 * Method to return the list of exercises.
	 * @param  none
	 * @return ArrayList<String>
	 * @see
	*/
	public ArrayList<String> getExerciseList()
	{
		return this.exList;
	}
	
	private static void parseHistory(String db, String date)
	{
		String token = new String(db);
		int ind1, ind2;
		int indsep;
		String name,reps,time,comment,wt;
		while(token.length() > 5)
		{
			ArrayList<String> exlist = new ArrayList<String>();
			ind1 = token.indexOf(",");
			name = token.substring(0,ind1);
			token = token.substring(ind1+1);
			ind2 = token.indexOf(",");
			indsep = token.indexOf("!");
			while(ind2 < indsep)
			{
				exlist.add(token.substring(0, ind2));
				token = token.substring(ind2+1);
				ind1 = ind2;
				ind2 = token.indexOf(",");
				indsep = token.indexOf("!");
			}
			
			exlist.add(token.substring(0, indsep));
			token = token.substring(indsep+1);
			ind2 = token.indexOf(",");
			reps = token.substring(0, ind2);
			token = token.substring(ind2+1);
			ind2 = token.indexOf(",");
			time = token.substring(0, ind2);
			token = token.substring(ind2+1);
			ind2 = token.indexOf(",");
			wt = token.substring(0, ind2);
			token = token.substring(ind2+1);
			ind2 = token.indexOf("*");
			comment = token.substring(0, ind2);
			token = token.substring(ind2+1);
			DBHistory entry = new DBHistory(date, name, reps, time, wt, comment, exlist);
			db_wodHistory.add(0,entry);
		}
	}	
	
	
	private static void writeToHistoryFile(Context ctx, String file, DBHistory entry)
	{
		try{
		FileOutputStream fos = ctx.openFileOutput(file, Context.MODE_APPEND);
		ArrayList<String> list = entry.getExerciseList();
		fos.write(entry.getName().getBytes());
		String delm = ",";
		String exEnd = "!";
		String wodEnd = "*";
		fos.write(delm.getBytes());
		for(int i = 0; i < list.size(); i++)
		{
			fos.write(list.get(i).getBytes());
			if(i!= list.size()-1)
			fos.write(delm.getBytes());
		}
		fos.write(exEnd.getBytes());
		fos.write(entry.getReps().getBytes());
		fos.write(delm.getBytes());
		fos.write(entry.getTime().getBytes());
		fos.write(delm.getBytes());
		fos.write(entry.getWeights().getBytes());
		fos.write(delm.getBytes());
		fos.write(entry.getComments().getBytes());
		fos.write(wodEnd.getBytes());
		fos.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	private static String readFileByte(FileInputStream fis) throws FileNotFoundException
	{
		String db = "";
		try {
			Scanner s = new java.util.Scanner(fis);
	        db = s.useDelimiter("\\A").next();
	    } catch (java.util.NoSuchElementException e) {
	         e.printStackTrace();
	    }

		return db;
	}

	private static void buildHistoryFile(BufferedReader buffreader, FileOutputStream fos) throws FileNotFoundException
	{
		try{
		String token;
		while(( token = buffreader.readLine())!= null)
		{
			fos.write(token.getBytes());
		}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}
	
	public static ArrayList<DBHistory> getHistory(String date, String name)
	{
		DBHistory entry;
		ArrayList<DBHistory> list = new ArrayList<DBHistory>();
		boolean readDate = false;
		for(int i = 0; i < db_wodHistory.size(); i++)
		{
			entry = db_wodHistory.get(i);
			if(name.equals(entry.getName()) && date.equals(entry.getDate()))
			{
				list.add(entry);
				readDate = true;
			}
			
			if(readDate && !date.equals(entry.getDate()))
			{
				break;
			}			
		}		
		return list;	
	}
		
	public static ArrayList<DBHistory> getHistoryByName(String name, String type)
	{
		DBHistory entry;
		ArrayList<DBHistory> list = new ArrayList<DBHistory>();

		if(type.equals("wod"))
		{
		for(int i = 0; i < db_wodHistory.size(); i++)
		{
			entry = db_wodHistory.get(i);
			if(name.equals(entry.getName()))
			{
				list.add(entry);
			}
			
		}
		}
		else if(type.equals("ex"))
		{
			for(int i = 0; i < db_wodHistory.size(); i++)
			{
				entry = db_wodHistory.get(i);
				ArrayList<String> exList = entry.getExerciseList();
				for(int j = 0; j< exList.size(); j++)
				{
					
					if(exList.get(j).contains(name))
					{
						String comment = entry.getName();
						DBHistory ex = new DBHistory(entry.getDate(), name, "0","0","0",comment, null);
						list.add(ex);
					}
				}
				
			}
		}
		
		return list;	
	}
	
	public static ArrayList<DBHistory> getHistoryByDate(String date)
	{
		DBHistory entry;
		ArrayList<DBHistory> list = new ArrayList<DBHistory>();
		boolean readDate = false;
		for(int i = 0; i < db_wodHistory.size(); i++)
		{
			entry = db_wodHistory.get(i);
			if(date.equals(entry.getDate()))
			{
				list.add(entry);
				readDate = true;
			}
			
			if(readDate && !date.equals(entry.getDate()))
			{
				break;
			}		
		}
		return list;
	}		
	
	
	
	public static ArrayList<DBHistory> getHistory()
	{
		return new ArrayList<DBHistory>(db_wodHistory);
	}	
	
	
	
	public static int getSize()
	{
		return db_wodHistory.size();
	}
	
	
	
	private static void createDB(Context ctx)
	{
		try{
		
		Resources myResources = ctx.getResources();
		InputStream inputStream = myResources.openRawResource(R.raw.h06012012);
		InputStreamReader inputreader = new InputStreamReader(inputStream);
		BufferedReader buffreader = new BufferedReader(inputreader);
		FileOutputStream fos = ctx.openFileOutput("06012012", Context.MODE_PRIVATE);
		buildHistoryFile(buffreader, fos);
		buffreader.close();
		inputreader.close();
		inputStream.close();
		fos.close();
		
		inputStream = myResources.openRawResource(R.raw.h06022012);
		inputreader = new InputStreamReader(inputStream);
		buffreader = new BufferedReader(inputreader);
		fos = ctx.openFileOutput("06022012", Context.MODE_PRIVATE);
		buildHistoryFile(buffreader, fos);
		buffreader.close();
		inputreader.close();
		inputStream.close();
		fos.close();
		
		inputStream = myResources.openRawResource(R.raw.h06032012);
		inputreader = new InputStreamReader(inputStream);
		buffreader = new BufferedReader(inputreader);
		fos = ctx.openFileOutput("06032012", Context.MODE_PRIVATE);
		buildHistoryFile(buffreader, fos);
		buffreader.close();
		inputreader.close();
		inputStream.close();
		fos.close();
		
		inputStream = myResources.openRawResource(R.raw.h06052012);
		inputreader = new InputStreamReader(inputStream);
		buffreader = new BufferedReader(inputreader);
		fos = ctx.openFileOutput("06052012", Context.MODE_PRIVATE);
		buildHistoryFile(buffreader, fos);
		buffreader.close();
		inputreader.close();
		inputStream.close();
		fos.close();
		
		fos = ctx.openFileOutput("date", Context.MODE_PRIVATE);
		String date = "05272012";
		fos.write(date.getBytes());
		fos.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
		
	@SuppressWarnings("static-access")
	public static void instantiateHistoryDB(Context ctx)
	{
		try
		{
		db_wodHistory = new ArrayList<DBHistory>();
		Calendar c = Calendar.getInstance();
		SimpleDateFormat format = new SimpleDateFormat("MMddyyyy");
		String date = format.format(c.getTime());
		File f = ctx.getFileStreamPath(date);
		createDB(ctx);
		if(!f.exists())
		{
			FileOutputStream fos = ctx.openFileOutput(date, Context.MODE_PRIVATE);
			fos.close();
		}
		
		FileInputStream fs = ctx.openFileInput("date");
		String firstDate = readFileByte(fs);
		fs.close();
		while(!date.equals(firstDate))
		{
			try{
			FileInputStream fis = ctx.openFileInput(date);
			String db = readFileByte(fis);
			parseHistory(db, date);
			fis.close();
			c.add(c.DATE, -1);
			date = format.format(c.getTime());
			f = ctx.getFileStreamPath(date);
			fis.close();
			}
			catch(Exception e)
			{
				e.printStackTrace();
				c.add(c.DATE, -1);
				date = format.format(c.getTime());
			}
		}
		}		
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	public static boolean createNewEntry(Context ctx, String date, String name, String reps, String time, String weights, String comments, ArrayList<String> exercises)
			{
				boolean success = true;
				DBHistory newEntry = new DBHistory(date, name, reps, time, weights, comments, exercises);
				
					if( !name.equals("0") && (!reps.equals("0") || !time.equals("0")) && exercises != null && exercises.size() > 0)
					{
						db_wodHistory.add(newEntry);
						writeToHistoryFile(ctx, date, newEntry);
						return success;
					}
					else
					{
						return !success;
					}				
			}			
}